package com.xuanwei.search.service;

import com.google.common.collect.Lists;
import com.xuanwei.search.dao.ProductDao;
import com.xuanwei.search.entity.index.ProductIndex;
import com.xuanwei.xwcommon.entity.dto.SimpleProductDto;
import com.xuanwei.xwcommon.enums.ProductListOrderType;
import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.search.TermQuery;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.metrics.stats.StatsAggregationBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.ResultsExtractor;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Optional;

/**
 * @Author jiangyong
 * @Description TODO
 * @Date 2019/6/27 20:13
 **/
@Service
@Slf4j
public class ProductSearchService {

    private ProductDao productDao;

    private ElasticsearchTemplate elasticsearchTemplate;

    public ProductSearchService(ProductDao productDao, ElasticsearchTemplate elasticsearchTemplate) {
        this.productDao = productDao;
        this.elasticsearchTemplate = elasticsearchTemplate;
    }

    /**
     * 添加商品到es
     *
     * @param productIndex 对象
     * @throws Exception
     */
    public void add(ProductIndex productIndex) throws Exception {
        if (productIndex.getId() == null) {
            throw new Exception("id is null");
        }
        productDao.save(productIndex);
    }

    /**
     * 搜索商品
     *
     * @param name       商品名称
     * @param categoryId 类目ID
     * @param orderBy    排序
     * @param page       当前页
     * @param pageSize   每页大小
     * @return 集合数据
     */
    public List<SimpleProductDto> search(String name, Integer categoryId,
                                         Integer orderBy,
                                         Integer page, Integer pageSize, Integer order) {
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if (!StringUtils.isEmpty(name)) {
            MatchQueryBuilder condition = QueryBuilders.matchQuery("name", name);
            boolQuery.must(condition);
        }
        if (categoryId != null) {
            TermQueryBuilder condition = QueryBuilders.termQuery("categoryId", categoryId);
            boolQuery.must(condition);
        }

        searchQueryBuilder.withQuery(boolQuery);
        String field = orderBy == null ? ProductListOrderType.PRICE.getField() : ProductListOrderType.getCode(orderBy);
        //1 升序 2 降序 默认升序
        if (order == null) {
            order = 1;
        }
        SortOrder sortOrder = order == 1 ? SortOrder.ASC : SortOrder.DESC;
        FieldSortBuilder sortBuilder = SortBuilders.fieldSort(field).order(sortOrder);
        searchQueryBuilder.withSort(sortBuilder);
        if (page == null) {
            page = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize);
        searchQueryBuilder.withPageable(pageRequest);
        searchQueryBuilder.withFields("id", "name", "minPrice", "mainImage", "minMarketPrice", "labelName", "saleNum");
        Page<ProductIndex> search = productDao.search(searchQueryBuilder.build());
        if (search != null) {
            List<ProductIndex> content = search.getContent();
            List<SimpleProductDto> dtos = Lists.newArrayListWithCapacity(content.size());
            content.forEach(s -> {
                SimpleProductDto simpleProductDto = new SimpleProductDto();
                simpleProductDto.setId(s.getId());
                simpleProductDto.setImage(s.getMainImage());
                simpleProductDto.setMarketPrice(s.getMinMarketPrice());
                simpleProductDto.setPrice(s.getMinPrice());
                simpleProductDto.setName(s.getName());
                simpleProductDto.setLabelName(s.getLabelName());
                simpleProductDto.setSaleNum(s.getSaleNum());
                dtos.add(simpleProductDto);
            });
            return dtos;
        }
        return null;
    }

    /**
     * 根据ID查询商品详情
     *
     * @param id ID
     * @return 详情
     */
    public ProductIndex findById(Integer id) {
        Optional<ProductIndex> optional = productDao.findById(id);
        boolean present = optional.isPresent();
        if (present) {
            return optional.get();
        }
        log.warn("the product is not exists:{}", id);
        return null;
    }


    public SimpleProductDto findSimpleProductById(Integer id) {
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        TermQueryBuilder termQuery = QueryBuilders.termQuery("id", id);
        boolQuery.must(termQuery);
        searchQueryBuilder.withQuery(boolQuery);
        searchQueryBuilder.withFields("id", "name", "minPrice", "mainImage", "minMarketPrice", "labelName", "saleNum");
        PageRequest pageRequest = PageRequest.of(0, 1);
        searchQueryBuilder.withPageable(pageRequest);
        Page<ProductIndex> search = productDao.search(searchQueryBuilder.build());
        if (search != null && search.getContent().size() != 0) {
            List<ProductIndex> content = search.getContent();
            ProductIndex productIndex = content.get(0);
            SimpleProductDto simpleProductDto = new SimpleProductDto();
            simpleProductDto.setId(productIndex.getId());
            simpleProductDto.setImage(productIndex.getMainImage());
            simpleProductDto.setMarketPrice(productIndex.getMinMarketPrice());
            simpleProductDto.setPrice(productIndex.getMinPrice());
            simpleProductDto.setName(productIndex.getName());
            simpleProductDto.setLabelName(productIndex.getLabelName());
            return simpleProductDto;
        }
        return null;
    }

    /**
     * 删除Es的商品
     *
     * @param id ID
     */
    public void deleteById(Integer id) {
        productDao.deleteById(id);
    }

}
